/*----------------------------------------------------------------------------
Owner(s): Shane Whitfield
$Copyright: $
$Id: 

Purpose  : Basic game object
----------------------------------------------------------------------------*/

#pragma once

#include "go.h"
#include "go_path.h"

/*--------------------------------------------------------------------------*/
// Forward declarations

class CGoHealStation;
class CGoMiningStation;

/*--------------------------------------------------------------------------*/
// Class CGoMobile declaration.
class CGoMobile	: public CGo
{
	typedef CGo super;

public:

	CGoMobile();
	
	//CGo Overrides
	virtual void	Update();
	
	void			SetSpeed(float i_speed);
	void			SetVelocity(Vector2f i_dir) {
						m_velocity = i_dir; }
	void			SetPath(const CGoPath* i_path);
	
	// $$$ BB (SAW) Can this be incorporated into SetSpeed()? If so
	//				we will lose the ablility to have something on a path with on speed
	//				then pop off and go at an already authored speed.. is that ok? Check gameplay.
	void			SetPathSpeed(float i_speed) {
						m_pathSpeed = i_speed; } 

protected:

	virtual bool	shouldBeMoving() const {
						return false; }
	
private:

	enum EState
	{
		BEGIN_ENUM(EState_),
		EState_Moving,
		EState_FollowingPath,
		EState_Stopped,
		END_ENUM(EState_)
	};
	
	void setState(EState i_state);

	EState			m_state;
	Vector2f		m_velocity;
	const CGoPath*	m_path;
	CFollowState	m_followState;
	float			m_pathSpeed;
};

/*--------------------------------------------------------------------------*/
// Class CGoHealer declaration.
class CGoHealer	: public CGoMobile
{
	typedef CGoMobile super;

public:

					CGoHealer();
	
	//CGo Overrides
	virtual void	Update();
	virtual void	Render();
	virtual EClass	GetClass() {
						return EClass_Healer;}
	
	void			SetHealTarget(CGoNode* newTarget) {
						m_healTarget = newTarget; }
	void			SetHealingStation(CGoHealStation* i_owner) {
						m_healStation = i_owner; }
	bool			IsTargetHealed() const {
						return m_healTarget->HasFullHealth(); }
	CGo*			GetHealTarget() {
						return m_healTarget; }
			

protected:

	//CGoMobile Overrrides
	virtual bool	shouldBeMoving() const {
						return m_state != EState_WaitingInjury; }
				
private:

	enum EState
	{
		EState_WaitingInjury,
		EState_MovingToInjury,
		EState_HealingInjury,
		EState_MovingHome
	};

	bool	isEnergyFull() const {
				return m_curHealingEnergy >= m_maxHealingEnergy; }
	bool	isEnergyEmpty() const {
				return m_curHealingEnergy <= 0.0f; }
	bool	hasEnoughEnergyForNewTarget() const {
				return (m_curHealingEnergy / m_maxHealingEnergy) > .7f; }
	void	replenishEnergy();
	void	healTarget();
	void	setState(EState i_state);
	void	updateVelocityToCircleTarget();
	void	logState();

	CGoNode*		m_healTarget;
	CGoHealStation*	m_healStation;
	EState			m_state;
	
	float			m_healingRange;
	float			m_curHealingEnergy;
	float			m_maxHealingEnergy;
};



/*--------------------------------------------------------------------------*/
// Class CGoMiner declaration.
class CGoMiner	: public CGoMobile
{
	typedef CGoMobile super;

public:

					CGoMiner();
	
	//CGo Overrides
	virtual void	Update();
	virtual void	Render();
	virtual EClass	GetClass() {
						return EClass_Miner;}
	
	void			SetMiningStation(CGoMiningStation* i_owner) {
						m_miningStation = i_owner; }
		

protected:

	//CGoMobile Overrrides
	virtual bool	shouldBeMoving() const {
						return m_state != EState_WaitingSearchPing; }
				
private:

	enum EState
	{
		EState_WaitingSearchPing,
		EState_SearchingForMiningTarget,
		EState_MovingToMinerals,
		EState_Mining,
		EState_MovingHome
	};

	void	mineTarget();
	void	setState(EState i_state);
	void	updateVelocityToCircleTarget();

	CGoMinerals*		m_miningTarget;
	CGoMiningStation*	m_miningStation;
	EState				m_state;
	float				m_tState;
	float				m_miningRange;
};


/*-----------------------------------EOF!-----------------------------------*/
